package com.leyou.order.utils;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.order.config.PayConfig;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.enums.PayState;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.mapper.OrderStatusMapper;
import com.leyou.order.pojo.Order;
import com.leyou.order.pojo.OrderStatus;
import com.leyou.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.github.wxpay.sdk.WXPayConstants.*;

/**
 * @author: HuYi.Zhang
 * @create: 2018-06-07 15:54
 **/
@Component
@Slf4j
public class PayHelper {
    @Autowired
    private WXPay wxPay;

    @Autowired
    private PayConfig config;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private OrderMapper orderMapper;

    public String createPayUrl(Long orderId, Long totalPay, String desc) {
        try {
            Map<String, String> data = new HashMap<>();
            // 商品描述
            data.put("body", desc);
            // 订单号
            data.put("out_trade_no", orderId.toString());
            //金额，单位是分
            data.put("total_fee", "1");
            //调用微信支付的终端IP（estore商城的IP）
            data.put("spbill_create_ip", "127.0.0.1");
            //回调地址
            data.put("notify_url", config.getNotifyUrl());
            // 交易类型为扫码支付
            data.put("trade_type", "NATIVE");

            //利用wxpay工具完成下单
            Map<String, String> result = this.wxPay.unifiedOrder(data);
            //判断通信和业务标识
            isSuccess(result);


            String url = result.get("code_url");
            return url;
        } catch (Exception e) {
            log.error("[微信下单] 创建预交易订单异常", e);
            return null;
        }
    }

    public void isSuccess(Map<String, String> result) {
        //判断通信标示
        String return_code = result.get("return_code");
        if (FAIL.equals(return_code)) {
            //通信失败
            log.error("[微信下单] 微信下单通信失败,原因:{}", result.get("return_msg"));
            throw new LyException(ExceptionEnum.WX_PAY_ORDER_FAIL);
        }

        //判断业务标识
        String result_code = result.get("result_code");
        if (FAIL.equals(result_code)) {
            //通信失败
            log.error("[微信下单] 微信下单通信错误,错误码:{},原因:{}", result.get("err_code"), result.get("err_code_des"));
            throw new LyException(ExceptionEnum.WX_PAY_ORDER_FAIL);
        }
    }


    public void isValidSign(Map<String, String> result) {
        try {
            //重新生成签名
            String sign1 = WXPayUtil.generateSignature(result, config.getKey(), SignType.HMACSHA256);
            String sign2 = WXPayUtil.generateSignature(result, config.getKey(), SignType.MD5);

            //和传过来的签名进行比较
            String sign = result.get("sign");
            if (!StringUtils.equals(sign, sign1) && !StringUtils.equals(sign, sign2)) {
                //签名有误,抛出异常
                throw new LyException(ExceptionEnum.INVALID_SIGN);
            }
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.INVALID_SIGN);
        }
    }

    public PayState queryPayState(Long orderId) {
        try {
            //请求参数
            Map<String, String> data = new HashMap<>();
            //订单号
            data.put("out_trade_no", orderId.toString());
            Map<String, String> result = wxPay.orderQuery(data);
            //校验结果
            isSuccess(result);
            //校验签名
            isValidSign(result);

            //订单金额
            String totalFeeStr = result.get("total_fee");
            //订单号
            if (StringUtils.isBlank(totalFeeStr)) {
                throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
            }
            //获取结果中的金额
            long totalFee = Long.valueOf(totalFeeStr);
            //获取订单
            Order order = orderMapper.selectByPrimaryKey(Long.valueOf(orderId));
            //校验订单金额
            if (totalFee !=/*order.getActualPay()*/ 1L) {
                //金额不符
                throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
            }
            /**
             * SUCCESS—支付成功
             *
             * REFUND—转入退款
             *
             * NOTPAY—未支付
             *
             * CLOSED—已关闭
             *
             * REVOKED—已撤销（付款码支付）
             *
             * USERPAYING--用户支付中（付款码支付）
             *
             * PAYERROR--支付失败(其他原因，如银行返回失败)
             *
             */
            String tradeState = result.get("trade_state");
            if (SUCCESS.equals(tradeState)){
                //支付成功
                //修改订单状态
                OrderStatus status = new OrderStatus();
                status.setStatus(OrderStatusEnum.PAYED.value());
                status.setOrderId(order.getOrderId());
                status.setPaymentTime(new Date());
                int count = orderStatusMapper.updateByPrimaryKeySelective(status);
                if (count != 1) {
                    throw new LyException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
                }
                //返回成功
                return PayState.SUCCESS;
            }

            if ("NOTPAY".equals(tradeState)||"USERPAYING".equals(tradeState)){
                return PayState.NOT_PAY;
            }

            return PayState.FAIL;

        } catch (Exception e) {
            return PayState.NOT_PAY;
        }
    }
}
